package com.ccb.testcenter.serviceMapingFactory.impl;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.tree.BaseElement;

import com.ccb.testcenter.config.entity.SegmentConfig;
import com.ccb.testcenter.configuration.Configuration;
import com.ccb.testcenter.parseexcel.ExcelHelper;
import com.ccb.testcenter.parseexcel.MyRow;
import com.ccb.testcenter.servicemaping.CustomRule;
import com.ccb.testcenter.servicemaping.DirectRule;
import com.ccb.testcenter.servicemaping.Field;
import com.ccb.testcenter.servicemaping.Segment;
import com.ccb.testcenter.serviceMapingFactory.SegmentFactory;
 /**
  * 
   * 类名：DefaultFilterFacctory
   * 创建人：li_dk
   * 修改人：li_dk
   * 创建时间：2017年1月6日 上午10:28:31
   * 修改时间：2017年1月6日 上午10:28:31
   * 文件版本：@version 1.0.0
   *
  */
public class DefaultSegmentFactory implements SegmentFactory{
	protected final Configuration configuration;
	public DefaultSegmentFactory(Configuration configuration) {
		this.configuration = configuration;
	 }
	    //A类型List存储
      private  List<Field> aList = new ArrayList<Field>();
       //D类型List存储
      private  List<Field> dList = new ArrayList<Field>();
	@Override
	public Segment buildSegment(SegmentConfig segmentConfig) throws Exception {
		   Segment segment = new Segment();
		   String  name = segmentConfig.getName();
		   String  root = segmentConfig.getName();
		   String  file = segmentConfig.getName();
		   String  sheetName = segmentConfig.getName();
		   segment.setRoot(root);
		    Element rootElement = DocumentHelper.createElement(name);
		    segment.setRootElement(rootElement);
			Sheet sheet;
			XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(file));
			sheet = workbook.getSheet(sheetName);
			parseExcel(sheet,rootElement,segment);	
		return segment;
	}
	/**
	 * 
	 * parseExcel(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @param sheet
	 * @param parentEle 
	 * 创建人：li_dk
	 * 修改人：li_dk
	 * 创建时间：2016年12月26日-下午1:57:22
	 * 修改时间：2016年12月26日-下午1:57:22
	 * type:void
	 * @exception: 
	 * @since  1.0.0
	 */
	private void parseExcel(Sheet sheet,Element parentEle,Segment segment){
		int rows = sheet.getPhysicalNumberOfRows();
		List<MyRow> all = new ArrayList<MyRow>();
		for(int i=2; i<rows; i++) {
			MyRow row = new MyRow(sheet.getRow(i));
			String fisrtStr = ExcelHelper.getCellValue(row.getRow().getCell(0));
			if(StringUtils.isNotEmpty(fisrtStr))
				all.add(row);
		}		
		List<MyRow> topRowList = new ArrayList<MyRow>();
		
		for(MyRow row : all) {
			String fisrtStr = ExcelHelper.getCellValue(row.getRow().getCell(0));
			if(!fisrtStr.startsWith("..")) {
				topRowList.add(row);
			}
		}
		
		Map<Integer,List<MyRow>> dblRowsMap = new HashMap<Integer, List<MyRow>>();
		for(int i=0; i<topRowList.size(); i++) {
			MyRow row = topRowList.get(i);
			List<MyRow> dblRows = new ArrayList<MyRow>();
			getChildren(all, row);
			int dblTimes = row.getDblTimes();
			for(int j=0;j<dblTimes; j++) {
				dblRows.add(row.deepClone());
			}
			dblRowsMap.put(i+1, dblRows);
//			}
			
		}
		
		for(Entry<Integer, List<MyRow>> entry : dblRowsMap.entrySet()) {
			topRowList.addAll(entry.getKey(),entry.getValue());
		}	
		changeToEle(topRowList, parentEle,segment);
	}
	 /**
	  * 
	  * change2Ele(这里用一句话描述这个方法的作用)
	  * (这里描述这个方法适用条件 – 可选)
	  * @param rows
	  * @param parentEle 
	  * 创建人：li_dk
	  * 修改人：li_dk
	  * 创建时间：2016年12月26日-下午1:57:08
	  * 修改时间：2016年12月26日-下午1:57:08
	  * type:void
	  * @exception: 
	  * @since  1.0.0
	  */
	private void changeToEle(List<MyRow> rows,Element parentEle,Segment segment) {
		Field obj=null;
		for(MyRow row : rows) {
			String name = ExcelHelper.getCellValue(row.getRow().getCell(0)).replace(".", ""); // 栏位项目名称
			String nameZh = ExcelHelper.getCellValue(row.getRow().getCell(1)); // 中文名称
			String length = ExcelHelper.getCellValue(row.getRow().getCell(3)); // XML输入长度
			Element ele = new BaseElement(name);
			changeToEle(row.getChildren(), ele,segment);
//			parentEle.addComment(nameZh);
			parentEle.add(ele);
			String mapType = ExcelHelper.getCellValue(row.getRow().getCell(12));
			String parameter = ExcelHelper.getCellValue(row.getRow().getCell(13));
			switch (mapType) {
			case "a":
				obj= new Field();
				obj.setElement(ele);
				obj.setLength(length);
				DirectRule directRule = new DirectRule();
				directRule.setName(parameter);
				obj.setConverter(directRule);
				aList.add(obj);
				break;
			case "b":
				// paramter 长度校验
				if (null != parameter && null != length) {
					// if(parameter.length()!=Integer.valueOf(length)){
					// throw new RuntimeException(name +":values length
					// not right");
					// }
					ele.addCDATA(parameter);
				}
				break;
			case "c":
				break;
			case "d":
				obj= new Field();
				obj.setElement(ele);
				obj.setLength(length);
				CustomRule customRule = configuration.getCustomRule(parameter);				
				obj.setConverter(customRule);
				dList.add(obj);
			default :
				obj= new Field();
				obj.setElement(ele);
				obj.setLength(length);			   
			}
			segment.setaList(aList);
			segment.setaList(dList);
			}
	}	
	 /**
	  * 
	  * getChildren(这里用一句话描述这个方法的作用)
	  * (这里描述这个方法适用条件 – 可选)
	  * @param all
	  * @param currentRow 
	  * 创建人：li_dk
	  * 修改人：li_dk
	  * 创建时间：2016年12月26日-下午1:48:13
	  * 修改时间：2016年12月26日-下午1:48:13
	  * type:void
	  * @exception: 
	  * @since  1.0.0
	  */
	private void getChildren(List<MyRow> all, MyRow currentRow) {
		List<MyRow> result = new ArrayList<MyRow>();
		int currentRowNum = currentRow.getNum();
		int pointNum = currentRow.getPointNum();
		for(int i=currentRowNum+1-2; i<all.size(); i++) {
			MyRow child = all.get(i);
			int childPointNum = child.getPointNum();
			if(childPointNum == pointNum+2) {
				getChildren(all, child);				
			}
			if(childPointNum > pointNum+2)
				continue;
			if(childPointNum < pointNum+2) 
				break;
			result.add(child);
			List<MyRow> copyList = cloneRow(child);
			result.addAll(copyList);
			
		}
		currentRow.setChildren(result);
	}
	 /**
	  * 
	  * cloneRow(克隆当前行)
	  * (这里描述这个方法适用条件 – 可选)
	  * @param row
	  * @return 
	  * 创建人：li_dk
	  * 修改人：li_dk
	  * 创建时间：2016年12月26日-下午1:48:03
	  * 修改时间：2016年12月26日-下午1:48:03
	  * type:List<MyRow>
	  * @exception: 
	  * @since  1.0.0
	  */
	private List<MyRow> cloneRow(MyRow row) {
		List<MyRow> result = new ArrayList<MyRow>();
		int dblTimes = row.getDblTimes();
		if(dblTimes>0) {
			for(int i=0; i<dblTimes; i++) {
				MyRow copyRow = row.deepClone();
				result.add(copyRow);
			}
		}
		return result;
	}
	}


